package com.ruoyi.web.controller.system;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.datasync.SyncDatabase;
import com.ruoyi.system.service.ISyncDatabaseService;

/**
 * 数据库备份任务Controller
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/backup/task")
public class DatabaseBackupTaskController extends BaseController
{
    @Autowired
    private ISyncDatabaseService syncDatabaseService;

    /**
     * 查询数据库备份任务列表
     */
    @PreAuthorize("@ss.hasPermi('system:backup:list')")
    @GetMapping("/list")
    public TableDataInfo list(SyncDatabase syncDatabase)
    {
        startPage();
        // 只查询启用了定时备份的数据库
        syncDatabase.setScheduleBackup("1");
        syncDatabase.setStatus("0"); // 状态正常
        List<SyncDatabase> list = syncDatabaseService.selectSyncDatabaseList(syncDatabase);
        return getDataTable(list);
    }

    /**
     * 导出数据库备份任务列表
     */
    @PreAuthorize("@ss.hasPermi('system:backup:export')")
    @Log(title = "数据库备份任务", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SyncDatabase syncDatabase)
    {
        syncDatabase.setScheduleBackup("1");
        syncDatabase.setStatus("0");
        List<SyncDatabase> list = syncDatabaseService.selectSyncDatabaseList(syncDatabase);
        ExcelUtil<SyncDatabase> util = new ExcelUtil<SyncDatabase>(SyncDatabase.class);
        util.exportExcel(response, list, "数据库备份任务数据");
    }

    /**
     * 获取数据库备份任务详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:backup:query')")
    @GetMapping(value = "/{dbId}")
    public AjaxResult getInfo(@PathVariable("dbId") Long dbId)
    {
        SyncDatabase database = syncDatabaseService.selectSyncDatabaseByDbId(dbId);
        if (database == null) {
            return AjaxResult.error("数据库不存在");
        }
        
        // 检查是否启用了定时备份
        if (!"1".equals(database.getScheduleBackup())) {
            return AjaxResult.error("该数据库未启用定时备份");
        }
        
        return AjaxResult.success(database);
    }

    /**
     * 修改数据库备份任务设置
     */
    @PreAuthorize("@ss.hasPermi('system:backup:edit')")
    @Log(title = "数据库备份任务", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SyncDatabase syncDatabase)
    {
        if (syncDatabase.getDbId() == null) {
            return AjaxResult.error("数据库ID不能为空");
        }
        
        // 确保只更新备份相关的设置
        SyncDatabase existingDatabase = syncDatabaseService.selectSyncDatabaseByDbId(syncDatabase.getDbId());
        if (existingDatabase == null) {
            return AjaxResult.error("数据库不存在");
        }
        
        // 只更新备份相关字段
        existingDatabase.setScheduleBackup(syncDatabase.getScheduleBackup());
        existingDatabase.setBackupCycle(syncDatabase.getBackupCycle());
        existingDatabase.setBackupTime(syncDatabase.getBackupTime());
        existingDatabase.setBackupServerId(syncDatabase.getBackupServerId());
        existingDatabase.setBackupPath(syncDatabase.getBackupPath());
        existingDatabase.setRemark(syncDatabase.getRemark());
        
        return toAjax(syncDatabaseService.updateDatabaseBackupSettings(existingDatabase));
    }

    /**
     * 手动执行数据库备份
     */
    @PreAuthorize("@ss.hasPermi('system:backup:execute')")
    @Log(title = "数据库备份任务", businessType = BusinessType.OTHER)
    @PostMapping("/execute/{dbId}")
    public AjaxResult executeBackup(@PathVariable("dbId") Long dbId)
    {
        SyncDatabase database = syncDatabaseService.selectSyncDatabaseByDbId(dbId);
        if (database == null) {
            return AjaxResult.error("数据库不存在");
        }
        
        if (!"1".equals(database.getScheduleBackup())) {
            return AjaxResult.error("该数据库未启用定时备份");
        }
        
        if (!"0".equals(database.getStatus())) {
            return AjaxResult.error("数据库状态异常，无法执行备份");
        }
        
        try {
            String backupFilePath = null;
            
            // 根据设置选择本地备份或远程备份
            if (database.getBackupServerId() != null) {
                // 远程备份
                backupFilePath = syncDatabaseService.remoteBackupDatabase(
                    dbId, database.getBackupServerId(), database.getBackupPath());
            } else {
                // 本地备份
                backupFilePath = syncDatabaseService.backupDatabase(dbId);
            }
            
            if (backupFilePath != null) {
                // 更新最后备份时间
                database.setLastBackupTime(new java.util.Date());
                syncDatabaseService.updateDatabaseBackupSettings(database);
                
                return AjaxResult.success("备份执行成功，文件路径：" + backupFilePath);
            } else {
                return AjaxResult.error("备份执行失败，请检查数据库连接和服务器配置");
            }
        } catch (Exception e) {
            logger.error("执行数据库备份失败", e);
            return AjaxResult.error("备份执行失败：" + e.getMessage());
        }
    }

    /**
     * 启用/停用数据库定时备份
     */
    @PreAuthorize("@ss.hasPermi('system:backup:edit')")
    @Log(title = "数据库备份任务", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SyncDatabase syncDatabase)
    {
        if (syncDatabase.getDbId() == null) {
            return AjaxResult.error("数据库ID不能为空");
        }
        
        SyncDatabase existingDatabase = syncDatabaseService.selectSyncDatabaseByDbId(syncDatabase.getDbId());
        if (existingDatabase == null) {
            return AjaxResult.error("数据库不存在");
        }
        
        existingDatabase.setScheduleBackup(syncDatabase.getScheduleBackup());
        
        return toAjax(syncDatabaseService.updateDatabaseBackupSettings(existingDatabase));
    }

    /**
     * 批量执行数据库备份
     */
    @PreAuthorize("@ss.hasPermi('system:backup:execute')")
    @Log(title = "数据库备份任务", businessType = BusinessType.OTHER)
    @PostMapping("/batchExecute")
    public AjaxResult batchExecuteBackup(@RequestBody Long[] dbIds)
    {
        if (dbIds == null || dbIds.length == 0) {
            return AjaxResult.error("请选择要备份的数据库");
        }

        int successCount = 0;
        int failCount = 0;
        StringBuilder resultMessage = new StringBuilder();

        for (Long dbId : dbIds) {
            try {
                SyncDatabase database = syncDatabaseService.selectSyncDatabaseByDbId(dbId);
                if (database == null || !"1".equals(database.getScheduleBackup()) || !"0".equals(database.getStatus())) {
                    failCount++;
                    resultMessage.append("数据库ID[").append(dbId).append("]状态异常，跳过备份\n");
                    continue;
                }

                String backupFilePath = null;
                if (database.getBackupServerId() != null) {
                    backupFilePath = syncDatabaseService.remoteBackupDatabase(
                        dbId, database.getBackupServerId(), database.getBackupPath());
                } else {
                    backupFilePath = syncDatabaseService.backupDatabase(dbId);
                }

                if (backupFilePath != null) {
                    successCount++;
                    database.setLastBackupTime(new java.util.Date());
                    syncDatabaseService.updateDatabaseBackupSettings(database);
                    resultMessage.append("数据库[").append(database.getDbName()).append("]备份成功\n");
                } else {
                    failCount++;
                    resultMessage.append("数据库[").append(database.getDbName()).append("]备份失败\n");
                }
            } catch (Exception e) {
                failCount++;
                resultMessage.append("数据库ID[").append(dbId).append("]备份异常：").append(e.getMessage()).append("\n");
            }
        }

        String message = String.format("批量备份完成：成功%d个，失败%d个\n%s",
            successCount, failCount, resultMessage.toString());

        if (failCount == 0) {
            return AjaxResult.success(message);
        } else {
            return AjaxResult.warn(message);
        }
    }

    /**
     * 删除数据库备份任务
     */
    @PreAuthorize("@ss.hasPermi('system:backup:remove')")
    @Log(title = "数据库备份任务", businessType = BusinessType.DELETE)
    @DeleteMapping("/{dbIds}")
    public AjaxResult remove(@PathVariable Long[] dbIds)
    {
        if (dbIds == null || dbIds.length == 0) {
            return AjaxResult.error("请选择要删除的备份任务");
        }

        int successCount = 0;
        int failCount = 0;
        StringBuilder resultMessage = new StringBuilder();

        for (Long dbId : dbIds) {
            try {
                SyncDatabase database = syncDatabaseService.selectSyncDatabaseByDbId(dbId);
                if (database == null) {
                    failCount++;
                    resultMessage.append("数据库ID[").append(dbId).append("]不存在\n");
                    continue;
                }

                logger.info("删除备份任务 - 数据库ID: {}, 数据库名: {}, 当前scheduleBackup: {}",
                    dbId, database.getDbName(), database.getScheduleBackup());

                // 禁用定时备份并删除相关的同步任务
                database.setScheduleBackup("0");
                database.setBackupCycle(null);
                database.setBackupTime(null);
                database.setBackupServerId(null);
                database.setBackupPath(null);
                database.setLastBackupTime(null);

                logger.info("设置scheduleBackup为0，准备更新数据库记录");

                int result = syncDatabaseService.updateDatabaseBackupSettings(database);
                logger.info("更新结果: {}", result);

                if (result > 0) {
                    successCount++;
                    resultMessage.append("数据库[").append(database.getDbName()).append("]备份任务删除成功\n");
                } else {
                    failCount++;
                    resultMessage.append("数据库[").append(database.getDbName()).append("]备份任务删除失败\n");
                }
            } catch (Exception e) {
                failCount++;
                resultMessage.append("数据库ID[").append(dbId).append("]删除异常：").append(e.getMessage()).append("\n");
            }
        }

        String message = String.format("删除备份任务完成：成功%d个，失败%d个\n%s",
            successCount, failCount, resultMessage.toString());

        if (failCount == 0) {
            return AjaxResult.success(message);
        } else {
            return AjaxResult.warn(message);
        }
    }
}
